package cn.com.tarotframework.config.advice;

import cn.com.tarotframework.utils.constants.TarotConstantUtils;
import cn.com.tarotframework.utils.log.TarotLogUtils;
import cn.com.tarotframework.utils.response.TarotCode;
import cn.com.tarotframework.utils.response.TarotResult;
import io.undertow.servlet.spec.HttpServletRequestImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.error.ErrorAttributeOptions;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.WebRequest;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * copyright (C), 2022, 塔罗牌基础架构
 *
 * @program: tarot-config-spring-boot-starter
 * @description: 自定义错误处理控制层
 * @author: xincan
 * @date: 2022/5/25 16:49
 * @version: 0.0.1-SNAPSHOT
 **/
@Slf4j
@RestController
public class TarotErrorExceptionController implements ErrorController {

    private final ErrorAttributes errorAttributes;

    public TarotErrorExceptionController(ErrorAttributes errorAttributes) {
        this.errorAttributes = errorAttributes;
    }

    @RequestMapping(value = {TarotConstantUtils.TAROT_EXCEPTION_REQ_REDIRECT_URL})
    public TarotResult<String> error(HttpServletRequest request, WebRequest webRequest) {
        // 获取springboot原生报错返回信息
        final ErrorAttributeOptions errorAttributeOptions = ErrorAttributeOptions.of(ErrorAttributeOptions.Include.STACK_TRACE);
        Map<String, Object> map = errorAttributes.getErrorAttributes(webRequest, errorAttributeOptions);
        //map.remove("trace"); // 移除 trace 以避免抛出错误详细信息
        TarotCode tarotCode = TarotCode.getTarotCode(Integer.parseInt(map.get("status").toString()));
        String requestType = request.getMethod();
        String requestMedia = StringUtils.hasText(request.getContentType()) ? request.getContentType() : "'default;charset=" + request.getCharacterEncoding()+ "'";
        String requestUrl = getPath(request);
        TarotLogUtils.printLog(tarotCode.message(), tarotCode.code(), requestType, requestMedia, requestUrl, "", "", "", null);
        return  TarotResult.error(tarotCode);
    }

    private String getPath(HttpServletRequest request) {
       String path = ((HttpServletRequestImpl) request).getOriginalServletPath();
        return request.getRequestURL().toString().replace(TarotConstantUtils.TAROT_EXCEPTION_REQ_REDIRECT_URL, path);
    }

}
